/*
** ShpBrk8.c  -  this file contains methods for the 8-noded tri-linear 
**               brick finite element shape.
**
**    The adopted numbering scheeme is shown below:
**
**         s
**        ^
**        |    (natural coord. system)
**        |
**         -----> r
**       /
**      /
**     t
**
**               8+---------------+7
**               +|              +|
**              + |             + |
**             +  |            +  |
**            +   |           +   |
**           +    |          +    |
**         4+---------------+3    |
**          |    5+---------|-----+6
**          |    +          |    +
**          |   +           |   +
**          |  +            |  +
**          | +             | +
**          |+              |+
**         1+---------------+2
**
**
**           Internal numbering:
**
**
**               7+---------------+6
**               +|              +|
**              + |             + |
**             +  |            +  |
**            +   |           +   |
**           +    |          +    |
**         3+---------------+2    |
**          |    4+---------|-----+5
**          |    +          |    +
**          |   +           |   +
**          |  +            |  +
**          | +             | +
**          |+              |+
**         0+---------------+1
**
**
** --------------------------------------------------------------------------
**
** Entry Points:
**
** --------------------------------------------------------------------------
**
** void InitBRICK8( void )
**
**      Initializes sub-class BRICK8.
**
** --------------------------------------------------------------------------
**
** static Telement_3d *NewBRICK8( void )
**
**      This method allocates memory for a given BRICK8 element shape 
**      and returns a pointer to the new object.
**
** --------------------------------------------------------------------------
**
** static void ReadReseqBRICK8 ( int *reseq )
**
**      reseq    -  node numbering resequecing vector          (  in )
**
**      Reads node numbering resequecing vector BRICK8 finite 
**      element shape class.
**
** --------------------------------------------------------------------------
**
** static void ReseqBRICK8 ( int *reseq )
**
**      reseq    -  node numbering resequecing vector          (  in )
**
**      Specifies node numbering resequecing for BRICK8 finite 
**      element shape class.
**
** --------------------------------------------------------------------------
**
** static void GetReseqBRICK8 ( int *reseq )
**
**      reseq    -  node numbering resequecing vector          ( out )
**
**      Gets resequence vector for BRICK8 finite element shape node
**      numbering.
**
** --------------------------------------------------------------------------
**
** static void ConnectBRICK8 ( Telement_3d *shp,
**                             int    *connect )
**
**      shp      -  given element shape                        (  in )
**      connect  -  connectivity of the given element shape    ( out )
**
**      Returns connectivity of a given BRICK8 finite element shape.
**
** --------------------------------------------------------------------------
**
** static void DerivMapBRICK8rst ( Telement_3d    *shp,
**                                 NatCoord  *gauss_rst, 
**                                 DerivNat  deriv_rst[8] )
**
**      shp           -   given element shape  (not used)      (  in )
**      gauss_rst     -   natural coords.                      (  in )
**      deriv_rst     -   partial derivative wrt r,s,t         ( out )
**
**      This routine  returns the  "map"  functions  derivatives  with
**      respect to  the natural  coordinates for  a 8-noded hexahedron
**      solid finite element shape. The "map" function derivatives are
**      evaluated at the given natural coordinates. Numbering scheme is 
**      same as that given above.
**
** --------------------------------------------------------------------------
**
** static int  DimBRICK8 ( Telement_3d *shp )
**
**      shp          -  given element shape  (not used)        (  in )
**
**      Returns dimension number of BRICK8 shape, ie. 3.
**
** --------------------------------------------------------------------------
**
** static void GaussTypeBRICK8 ( Telement_3d    *shp,
**                               GaussType *gauss_type )
**
**      shp        -  given element shape (not used)             (  in )
**      GaussType  -  returned Gauss integration type            ( out )
**
**      Returns the Gauss integration type which is consistent with 
**      this element shape, i.e., CUBE_QUADRATURE.
**
** --------------------------------------------------------------------------
**
** static int  GetFirstEdgeBRICK8 ( Telement_3d    *shp,
**                                  int       *num_verts,
**                                  int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      num_verts  -  number edge verts                          ( out )
**      connect    -  edge connectivity                          ( out )
**
**      Gets no. of verts and connectivity of first edge of given shape.
**      The verts are returned in sequential order along the edge.
**
** --------------------------------------------------------------------------
**
** static int  GetNextEdgeBRICK8 ( Telement_3d    *shp,
**                                 int       *num_verts,
**                                 int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      num_verts  -  number edge verts                          ( out )
**      connect    -  edge connectivity                          ( out )
**
**      Gets no. of verts and connectivity of next edge of given shape.  
**      The verts are returned in sequential order along the edge.
**      If there is no other edge returns a false (0) status.
**      Otherwise, it returns a true (1) status.
**
** --------------------------------------------------------------------------
**
** static int  GetFirstFaceBRICK8 ( Telement_3d    *shp,
**                                  int       *num_verts,
**                                  int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      num_verts  -  number face verts                          ( out )
**      connect    -  face connectivity                          ( out )
**
**      Gets no. of verts and connectivity of first face of given shape.
**      The verts are returned in sequential order along the face.
**
** --------------------------------------------------------------------------
**
** static int  GetNextFaceBRICK8 ( Telement_3d    *shp,
**                                 int       *num_verts,
**                                 int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      num_verts  -  number face verts                          ( out )
**      connect    -  face connectivity                          ( out )
**
**      Gets no. of verts and connectivity of next face of given shape.  
**      The verts are returned in sequential order along the face.
**      If there is no other face returns a false (0) status.
**      Otherwise, it returns a true (1) status.
**
** --------------------------------------------------------------------------
**
** static int  GetShpEdgeBRICK8 ( Telement_3d    *shp,
**                                int       corners[],
**                                ShapeType *type,
**                                int       *num_nodes,
**                                int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      corners    -  corners of edge                            (  in )
**      type       -  returned edge shape type                   ( out )
**      num_nodes  -  number edge nodes                          ( out )
**      connect    -  edge connectivity                          ( out )
**
**      Gets shape type, no. of nodes, and connectivity of an edge of 
**      given shape for a given pair of corner nodes.
**      The returned edge shape type is LINE2.
**
** --------------------------------------------------------------------------
**
** static int  GetShpFaceBRICK8 ( Telement_3d    *shp,
**                                int       corners[],
**                                ShapeType *type,
**                                int       *num_nodes,
**                                int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      corners    -  corners of face                            (  in )
**      type       -  returned face shape type                   ( out )
**      num_nodes  -  number face nodes                          ( out )
**      connect    -  face connectivity                          ( out )
**
**      Gets shape type, no. of nodes, and connectivity of a face of 
**      given shape for a given triple of corner nodes.
**      The returned face shape type is QUAD4.
**
** --------------------------------------------------------------------------
**
** static void GetShpDomainBRICK8 ( Telement_3d    *shp,
**                                  ShapeType *type,
**                                  int       *num_nodes,
**                                  int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      type       -  returned domain shape type                 ( out )
**      num_nodes  -  number domain nodes                        ( out )
**      connect    -  domain connectivity                        ( out )
**
**      Gets shape type, no. of nodes, and connectivity of given shape.
**      The returned shape type is BRICK8 and the number of domain nodes
**      is 8.
**
** --------------------------------------------------------------------------
**
** static void MakeBRICK8 ( Telement_3d *shp,
**                          int    *connect )
**
**      shp      -  given element shape                        (  in )
**      connect  -  connectivity of the given element          (  in )
**
**      Makes a BRICK8 element shape of given connectivity.
**      Connectivity is ordered according to the class node 
**      resequencing data.
**
** --------------------------------------------------------------------------
**
** static void MakeDefaultBRICK8 ( Telement_3d *shp,
**                                 int    *connect )
**
**      shp      -  given element shape                        (  in )
**      connect  -  connectivity of the given element          (  in )
**
**      Makes a BRICK8 element shape of given connectivity.
**      The connectivity is assumed in the default class sequence.
**
** --------------------------------------------------------------------------
**
** static void MapFuncBRICK8 ( Telement_3d    *shp,
**                             NatCoord  *nat_coord, 
**                             ShapeVal  *shape )
**
**      shp          -  given element shape (not used)         (  in )
**      nat_coord   -   natural coords.                        (  in )
**      shape       -   shape funcs. evaluated at given pt.    ( out )
**
**      This routine returns the "map" functions for  a  8-noded solid
**      hexahedron  element shape.  The "map" functions are  evaluated
**      at the given natural coordinates. 
**
** --------------------------------------------------------------------------
**
** static void NodalNatCoordBRICK8 ( Telement_3d    *shp,
**                                   NatCoord  *coord )
**
**      shp         -   given element shape                    (  in )
**      coords      -   natural coordinates of its nodes       ( out )
**
**      Returns shape natural nodal coordinates.
**
** --------------------------------------------------------------------------
**
** static int  NumNodesBRICK8 ( Telement_3d *shp )
**
**      shp          -  given element shape  (not used)        (  in )
**
**      Returns number of nodes in a 8-noded brick shape, ie. 8.
**
** --------------------------------------------------------------------------
**
** static int  ReadBRICK8 ( Telement_3d *shp, int *conn )
**
**      shp           -  Given element shape                   (  in )
**      conn          -  Connectivity of element               (  in )
**      
**      This method reads nodal connectivity  data of a given "BRICK8" 
**      shape element.
**
** --------------------------------------------------------------------------
**
** version: 1-000
**
** history: Created:   30-Jul-96   Luiz Fernando Martha
**              Stolen from Femoop and modified.
**
**          Modified:  19-Oct-98   Joaquim Bento Cavalcante Neto
**              Modified some methods to agree with other shape modules.
**
** Modified:  Novem/2000 - Antonio Miranda (amiranda)
**      Changed the input of read method (FILE -> int *conn)
**
**
** --------------------------------------------------------------------------
*/

/* Global variables and symbols           */

#define _SHPBRICK8_C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "shp.h"


/*  Local variables and symbols  */

/*
** --------------------------------------------------------------------------
** Local data structures:
**
*/

/* Resequence node numbering vector:
 */
static int  rs[8] = {  0,  1,  2,  3,  4,  5,  6,  7  };

/* Edge and Face lists:
 */
#define NEDGES  12
static int curr_edge = 0;;
static int el[NEDGES][2] =  { {   0,  1  },
                              {   1,  2  },
                              {   2,  3  },
                              {   3,  0  },
                              {   0,  4  },
                              {   1,  5  },
                              {   2,  6  },
                              {   3,  7  },
                              {   4,  5  },
                              {   5,  6  },
                              {   6,  7  },
                              {   7,  4  } };

#define NFACES  6
static int curr_face = 0;
static int fl[NFACES][4] =  { {   0,  1,  2,  3  },
                              {   0,  4,  5,  1  },
                              {   1,  5,  6,  2  },
                              {   2,  6,  7,  3  },
                              {   3,  7,  4,  0  },
                              {   4,  7,  6,  5  } };

/* Use quadrature 2x2x2 = 8 gauss point */
static int num_gauss_point = 8;
static NatCoord gauss_rst[8] = {
  {+0.577350269189626, +0.577350269189626, +0.577350269189626},
  {-0.577350269189626, +0.577350269189626, +0.577350269189626},
  {+0.577350269189626, -0.577350269189626, +0.577350269189626},
  {-0.577350269189626, -0.577350269189626, +0.577350269189626},
  {+0.577350269189626, +0.577350269189626, -0.577350269189626},
  {-0.577350269189626, +0.577350269189626, -0.577350269189626},
  {+0.577350269189626, -0.577350269189626, -0.577350269189626},
  {-0.577350269189626, -0.577350269189626, -0.577350269189626}
};
static GaussWgt gauss_wgt[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

static ShapeVal shape_rst[8][8];
static DerivNat deriv_rst[8][8];

/* Local entry points: */

static Telement_3d *NewBRICK8  ( void );
static void ReadReseqBRICK8    ( int * );
static void ReseqBRICK8        ( int * );
static void GetReseqBRICK8     ( int * );
static void ConnectBRICK8      ( Telement_3d *, int * );
static void DerivMapBRICK8rst  ( Telement_3d *, NatCoord *, DerivNat *);
static int  DimBRICK8          ( Telement_3d * );
static void MapFuncBRICK8_i    ( Telement_3d *, int , ShapeVal ** );

static int    NumGaussPoint      (void);
static void   DerivMapBRICK8_i   ( Telement_3d *, int, DerivNat **);
static double GaussWgtBRICK8_i   ( Telement_3d *shp, int i);

static int  GetFirstEdgeBRICK8 ( Telement_3d *, int *, int [] );
static int  GetNextEdgeBRICK8  ( Telement_3d *, int *, int [] );
static int  GetFirstFaceBRICK8 ( Telement_3d *, int *, int [] );
static int  GetNextFaceBRICK8  ( Telement_3d *, int *, int [] );
static int  GetShpEdgeBRICK8   ( Telement_3d *, int [], AuxShapeType *, int *, int [] );
static int  GetShpFaceBRICK8   ( Telement_3d *, int [], AuxShapeType *, int *, int [] );
static void GetShpDomainBRICK8 ( Telement_3d *, ShapeType *, int *, int[] );
static void MakeBRICK8         ( Telement_3d *, int * );
static void MakeDefaultBRICK8  ( Telement_3d *, int * );
static void MapFuncBRICK8      ( Telement_3d *, NatCoord *, ShapeVal * );
static void NodalNatCoordBRICK8( Telement_3d *, NatCoord * );
static int  NumNodesBRICK8     ( Telement_3d * );
static int  ReadBRICK8         ( Telement_3d *, int * );




/* Public Entry Points: */


/* ============================== InitBRICK8 ================================ */

void InitBRICK8( void )
{
   int i;

   shape_class[NF_BRICK8].New                   =    NewBRICK8;
   shape_class[NF_BRICK8].readresequence        =    ReadReseqBRICK8;
   shape_class[NF_BRICK8].resequence            =    ReseqBRICK8;
   shape_class[NF_BRICK8].getresequence         =    GetReseqBRICK8;
   shape_class[NF_BRICK8].connectivity          =    ConnectBRICK8;
   shape_class[NF_BRICK8].shapefunc             =    MapFuncBRICK8;
   shape_class[NF_BRICK8].shapefunc_i           =    MapFuncBRICK8_i;

   shape_class[NF_BRICK8].derivmaprst           =    DerivMapBRICK8rst;
   shape_class[NF_BRICK8].derivshprst           =    DerivMapBRICK8rst;
   shape_class[NF_BRICK8].derivmap_i            =    DerivMapBRICK8_i;
   shape_class[NF_BRICK8].derivshp_i            =    DerivMapBRICK8_i;

   shape_class[NF_BRICK8].derivxyz              =    shp_derivXYZ;
   shape_class[NF_BRICK8].numgausspoint         =    NumGaussPoint;
   shape_class[NF_BRICK8].bmatrix               =    shp_BMatrix;
   shape_class[NF_BRICK8].gaussw_i              =    GaussWgtBRICK8_i;

   shape_class[NF_BRICK8].dim                   =    DimBRICK8;
   shape_class[NF_BRICK8].free                  =    shp_freeshape;
   shape_class[NF_BRICK8].gausstonode           =    shp_gausstonode;
   shape_class[NF_BRICK8].jacobian              =    shp_jacobian;
//   shape_class[NF_BRICK8].gausstype             =    GaussTypeBRICK8;
   shape_class[NF_BRICK8].getfirstedge          =    GetFirstEdgeBRICK8;
   shape_class[NF_BRICK8].getnextedge           =    GetNextEdgeBRICK8;
   shape_class[NF_BRICK8].getfirstface          =    GetFirstFaceBRICK8;
   shape_class[NF_BRICK8].getnextface           =    GetNextFaceBRICK8;
   shape_class[NF_BRICK8].getshpedge            =    GetShpEdgeBRICK8;
   shape_class[NF_BRICK8].getshpface            =    GetShpFaceBRICK8;
   shape_class[NF_BRICK8].getshpdomain          =    GetShpDomainBRICK8;
   shape_class[NF_BRICK8].getverts              =    ConnectBRICK8;
   shape_class[NF_BRICK8].isinterface           =    shp_isinterface;
   shape_class[NF_BRICK8].localsys              =    shp_localsyssolid;
   shape_class[NF_BRICK8].make                  =    MakeBRICK8;
   shape_class[NF_BRICK8].makedefault           =    MakeDefaultBRICK8;
   shape_class[NF_BRICK8].mapfunc               =    MapFuncBRICK8;
   shape_class[NF_BRICK8].nodalnatcoord         =    NodalNatCoordBRICK8;
   shape_class[NF_BRICK8].nodetovertex          =    shp_nodetovertex;
   shape_class[NF_BRICK8].nummapnodes           =    NumNodesBRICK8;
   shape_class[NF_BRICK8].numshpnodes           =    NumNodesBRICK8;
   shape_class[NF_BRICK8].numverts              =    NumNodesBRICK8;
   shape_class[NF_BRICK8].print                 =    shp_printshape;
   shape_class[NF_BRICK8].read                  =    ReadBRICK8;

   for (i = 0; i < num_gauss_point; i++)
   {
     MapFuncBRICK8 (NULL, &gauss_rst[i], shape_rst[i]);
     DerivMapBRICK8rst ( NULL, &gauss_rst[i], deriv_rst[i]);
   }
}


/* =============================== NewBRICK8 ================================ */

static Telement_3d *NewBRICK8 ( void )
{
   Telement_3d  *shp;

   shp = new Telement_3d;

   shp->type = NF_BRICK8;

   return( shp );
}


/* ============================ ReadReseqBRICK8 ============================= */

static void ReadReseqBRICK8 ( int *reseq )
{
   int i;

   for( i=0; i<8; i++ )
        rs[i] = reseq[i] - 1;
}


/* ============================== ReseqBRICK8 =============================== */

static void ReseqBRICK8 ( int *reseq )
{
   int i;

   for( i=0; i<8; i++ )
    rs[i] = reseq[i];
}


/* ============================= GetReseqBRICK8 ============================= */

static void GetReseqBRICK8 ( int *reseq )
{
   int i;

   for( i=0; i<8; i++ )
    reseq[i] = rs[i];
}


/* =============================== ConnectBRICK8 ============================ */

static void ConnectBRICK8 ( Telement_3d *shp,
                            int    *connect )
{
   connect[0] = shp->inc[0];
   connect[1] = shp->inc[1];
   connect[2] = shp->inc[2];
   connect[3] = shp->inc[3];
   connect[4] = shp->inc[4];
   connect[5] = shp->inc[5];
   connect[6] = shp->inc[6];
   connect[7] = shp->inc[7];
}

/* ============================ MapFuncBRICK8 =============================== */

static void MapFuncBRICK8 ( Telement_3d   *shp,
                            NatCoord *nat_coord, 
                            ShapeVal *shape )
{
   double  r, s, t;

   ignore (shp);

   r = nat_coord->r;
   s = nat_coord->s;
   t = nat_coord->t;
 
   shape[ 0] = 0.125*(1.0-r)*(1.0-s)*(1.0+t);
   shape[ 1] = 0.125*(1.0+r)*(1.0-s)*(1.0+t);
   shape[ 2] = 0.125*(1.0+r)*(1.0+s)*(1.0+t);
   shape[ 3] = 0.125*(1.0-r)*(1.0+s)*(1.0+t);
   shape[ 4] = 0.125*(1.0-r)*(1.0-s)*(1.0-t);
   shape[ 5] = 0.125*(1.0+r)*(1.0-s)*(1.0-t);
   shape[ 6] = 0.125*(1.0+r)*(1.0+s)*(1.0-t);
   shape[ 7] = 0.125*(1.0-r)*(1.0+s)*(1.0-t);
}


/* ============================ MapFuncBRICK8_i =============================== */

static void MapFuncBRICK8_i (Telement_3d   *shp, int i, ShapeVal **shape )
{
  if (i < 0 || i > num_gauss_point)
  {
    *shape = NULL;
    return;
  }
  *shape = shape_rst[i];
}

/* ========================== NodalNatCoordBRICK8 =========================== */

static void NodalNatCoordBRICK8 ( Telement_3d    *shp,
                                  NatCoord  *coord )
{
   ignore (shp);

   coord[0].r = -1.0; coord[0].s = -1.0; coord[0].t =  1.0;
   coord[1].r =  1.0; coord[1].s = -1.0; coord[1].t =  1.0;
   coord[2].r =  1.0; coord[2].s =  1.0; coord[2].t =  1.0;
   coord[3].r = -1.0; coord[3].s =  1.0; coord[3].t =  1.0;

   coord[4].r = -1.0; coord[4].s = -1.0; coord[4].t = -1.0;
   coord[5].r =  1.0; coord[5].s = -1.0; coord[5].t = -1.0;
   coord[6].r =  1.0; coord[6].s =  1.0; coord[6].t = -1.0;
   coord[7].r = -1.0; coord[7].s =  1.0; coord[7].t = -1.0;
}


/* ========================== DerivMapBRICK8rst ============================= */

static void DerivMapBRICK8rst ( Telement_3d   *shp,
                                NatCoord *gauss_rst,
                                DerivNat *deriv_rst )
{
    double  r, s, t;

    ignore (shp);

    r = gauss_rst->r;
    s = gauss_rst->s;
    t = gauss_rst->t;
 
    deriv_rst[0].r = -0.125*(1.0-s)*(1.0+t);
    deriv_rst[1].r =  0.125*(1.0-s)*(1.0+t);
    deriv_rst[2].r =  0.125*(1.0+s)*(1.0+t);
    deriv_rst[3].r = -0.125*(1.0+s)*(1.0+t);
    deriv_rst[4].r = -0.125*(1.0-s)*(1.0-t);
    deriv_rst[5].r =  0.125*(1.0-s)*(1.0-t);
    deriv_rst[6].r =  0.125*(1.0+s)*(1.0-t);
    deriv_rst[7].r = -0.125*(1.0+s)*(1.0-t);
 
    deriv_rst[0].s = -0.125*(1.0-r)*(1.0+t);
    deriv_rst[1].s = -0.125*(1.0+r)*(1.0+t);
    deriv_rst[2].s =  0.125*(1.0+r)*(1.0+t);
    deriv_rst[3].s =  0.125*(1.0-r)*(1.0+t);
    deriv_rst[4].s = -0.125*(1.0-r)*(1.0-t);
    deriv_rst[5].s = -0.125*(1.0+r)*(1.0-t);
    deriv_rst[6].s =  0.125*(1.0+r)*(1.0-t);
    deriv_rst[7].s =  0.125*(1.0-r)*(1.0-t);
 
    deriv_rst[0].t =  0.125*(1.0-r)*(1.0-s);
    deriv_rst[1].t =  0.125*(1.0+r)*(1.0-s);
    deriv_rst[2].t =  0.125*(1.0+r)*(1.0+s);
    deriv_rst[3].t =  0.125*(1.0-r)*(1.0+s);
    deriv_rst[4].t = -0.125*(1.0-r)*(1.0-s);
    deriv_rst[5].t = -0.125*(1.0+r)*(1.0-s);
    deriv_rst[6].t = -0.125*(1.0+r)*(1.0+s);
    deriv_rst[7].t = -0.125*(1.0-r)*(1.0+s);
}


/* =============================== DimBRICK8 ================================ */

static int DimBRICK8( Telement_3d *shp )
{  
   ignore (shp);

   return ( 3 );
}



/* ============================== NumGaussPoint =========================== */
static int NumGaussPoint (void)
{
  return (num_gauss_point);
}

/* ============================== DerivMapBRICK8_i =========================== */
static void DerivMapBRICK8_i  ( Telement_3d *shp, int i, DerivNat **ptr)
{
  if (i < 0 || i > 7)
  {
    ptr = NULL;
    return;
  }
  *ptr = deriv_rst[i];
}


/* ============================== GaussWgtBRICK8_i =========================== */
static double GaussWgtBRICK8_i  ( Telement_3d *shp, int i)
{
  if (i < 0 || i > 7)
    return 0.0;

  return (gauss_wgt[i]);
}


/* ============================== GaussTypeBRICK8 =========================== */

#if 0
static void GaussTypeBRICK8 ( Telement_3d    *shp,
                              GaussType *gauss_type )
{
   ignore (shp);

   *gauss_type = CUBE_QUADRATURE;
}
#endif

/* ============================= GetFirstEdgeBRICK8 ======================== */

static int  GetFirstEdgeBRICK8 ( Telement_3d    *shp,
                                 int       *num_verts,
                                 int       connect[] )
{
   *num_verts = 2;
   curr_edge = 0;

   connect[0] = shp->inc[el[curr_edge][0]];
   connect[1] = shp->inc[el[curr_edge][1]];
   return( 1 );
}


/* ============================= GetNextEdgeBRICK8 ========================= */

static int  GetNextEdgeBRICK8 ( Telement_3d    *shp,
                                int       *num_verts,
                                int       connect[] )
{
   *num_verts = 2;
   curr_edge++;

   if( curr_edge >= NEDGES )
    return( 0 );

   connect[0] = shp->inc[el[curr_edge][0]];
   connect[1] = shp->inc[el[curr_edge][1]];
   return( 1 );
}


/* ============================= GetFirstFaceBRICK8 ======================== */

static int  GetFirstFaceBRICK8 ( Telement_3d    *shp,
                                 int       *num_verts,
                                 int       connect[] )
{
   *num_verts = 4;
   curr_face = 0;

   connect[0] = shp->inc[fl[curr_face][0]];
   connect[1] = shp->inc[fl[curr_face][1]];
   connect[2] = shp->inc[fl[curr_face][2]];
   connect[3] = shp->inc[fl[curr_face][3]];
   return( 1 );
}


/* ============================= GetNextFaceBRICK8 ========================= */

static int  GetNextFaceBRICK8 ( Telement_3d    *shp,
                                int       *num_verts,
                                int       connect[] )
{
   *num_verts = 4;
   curr_face++;

   if( curr_face >= NFACES )
    return( 0 );

   connect[0] = shp->inc[fl[curr_face][0]];
   connect[1] = shp->inc[fl[curr_face][1]];
   connect[2] = shp->inc[fl[curr_face][2]];
   connect[3] = shp->inc[fl[curr_face][3]];
   return( 1 );
}


/* ============================= GetShpEdgeBRICK8 ========================== */

static int  GetShpEdgeBRICK8 ( Telement_3d    *shp,
                               int       corners[],
                               AuxShapeType *type,
                               int       *num_nodes,
                               int       connect[] )
{
   int          status = 0;

   *type = LINE2;
   *num_nodes = 2;

   if( corners[0] == shp->inc[0] )
   {
    connect[0] = shp->inc[0];
    if( corners[1] == shp->inc[3] )
    {
     connect[1] = shp->inc[3];
     status = 1;
    }
    else if( corners[1] == shp->inc[1] )
    {
     connect[1] = shp->inc[1];
     status = 1;
    }
    else if( corners[1] == shp->inc[4] )
    {
     connect[1] = shp->inc[4];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[1] )
   {
    connect[0] = shp->inc[1];
    if( corners[1] == shp->inc[0] )
    {
     connect[1] = shp->inc[0];
     status = 1;
    }
    else if( corners[1] == shp->inc[2] )
    {
     connect[1] = shp->inc[2];
     status = 1;
    }
    else if( corners[1] == shp->inc[5] )
    {
     connect[1] = shp->inc[5];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[2] )
   {
    connect[0] = shp->inc[2];
    if( corners[1] == shp->inc[1] )
    {
     connect[1] = shp->inc[1];
     status = 1;
    }
    else if( corners[1] == shp->inc[3] )
    {
     connect[1] = shp->inc[3];
     status = 1;
    }
    else if( corners[1] == shp->inc[6] )
    {
     connect[1] = shp->inc[6];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[3] )
   {
    connect[0] = shp->inc[3];
    if( corners[1] == shp->inc[2] )
    {
     connect[1] = shp->inc[2];
     status = 1;
    }
    else if( corners[1] == shp->inc[0] )
    {
     connect[1] = shp->inc[0];
     status = 1;
    }
    else if( corners[1] == shp->inc[7] )
    {
     connect[1] = shp->inc[7];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[4] )
   {
    connect[0] = shp->inc[4];
    if( corners[1] == shp->inc[7] )
    {
     connect[1] = shp->inc[7];
     status = 1;
    }
    else if( corners[1] == shp->inc[5] )
    {
     connect[1] = shp->inc[5];
     status = 1;
    }
    else if( corners[1] == shp->inc[0] )
    {
     connect[1] = shp->inc[0];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[5] )
   {
    connect[0] = shp->inc[5];
    if( corners[1] == shp->inc[4] )
    {
     connect[1] = shp->inc[4];
     status = 1;
    }
    else if( corners[1] == shp->inc[6] )
    {
     connect[1] = shp->inc[6];
     status = 1;
    }
    else if( corners[1] == shp->inc[1] )
    {
     connect[1] = shp->inc[1];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[6] )
   {
    connect[0] = shp->inc[6];
    if( corners[1] == shp->inc[5] )
    {
     connect[1] = shp->inc[5];
     status = 1;
    }
    else if( corners[1] == shp->inc[7] )
    {
     connect[1] = shp->inc[7];
     status = 1;
    }
    else if( corners[1] == shp->inc[2] )
    {
     connect[1] = shp->inc[2];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[7] )
   {
    connect[0] = shp->inc[7];
    if( corners[1] == shp->inc[6] )
    {
     connect[1] = shp->inc[6];
     status = 1;
    }
    else if( corners[1] == shp->inc[4] )
    {
     connect[1] = shp->inc[4];
     status = 1;
    }
    else if( corners[1] == shp->inc[3] )
    {
     connect[1] = shp->inc[3];
     status = 1;
    }
   }

   return( status );
}


/* ============================= GetShpFaceBRICK8 ========================== */

static int  GetShpFaceBRICK8 ( Telement_3d    *shp,
                               int       corners[],
                               AuxShapeType *type,
                               int       *num_nodes,
                               int       connect[] )
{
   int          status = 0;

   *type = QUAD4;
   *num_nodes = 4;

   if( corners[0] == shp->inc[0] )
   {
    connect[0] = shp->inc[0];
    if( (corners[1] == shp->inc[1]) && (corners[2] == shp->inc[3]) )
    {
     connect[1] = shp->inc[1];
     connect[2] = shp->inc[2];
     connect[3] = shp->inc[3];
     status = 1;
    }
    else if( (corners[1] == shp->inc[3]) && (corners[2] == shp->inc[4]) )
    {
     connect[1] = shp->inc[3];
     connect[2] = shp->inc[7];
     connect[3] = shp->inc[4];
     status = 1;
    }
    else if( (corners[1] == shp->inc[4]) && (corners[2] == shp->inc[1]) )
    {
     connect[1] = shp->inc[4];
     connect[2] = shp->inc[5];
     connect[3] = shp->inc[1];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[1] )
   {
    connect[0] = shp->inc[1];
    if( (corners[1] == shp->inc[2]) && (corners[2] == shp->inc[0]) )
    {
     connect[1] = shp->inc[2];
     connect[2] = shp->inc[3];
     connect[3] = shp->inc[0];
     status = 1;
    }
    else if( (corners[1] == shp->inc[0]) && (corners[2] == shp->inc[5]) )
    {
     connect[1] = shp->inc[0];
     connect[2] = shp->inc[4];
     connect[3] = shp->inc[5];
     status = 1;
    }
    else if( (corners[1] == shp->inc[5]) && (corners[2] == shp->inc[2]) )
    {
     connect[1] = shp->inc[5];
     connect[2] = shp->inc[6];
     connect[3] = shp->inc[2];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[2] )
   {
    connect[0] = shp->inc[2];
    if( (corners[1] == shp->inc[3]) && (corners[2] == shp->inc[1]) )
    {
     connect[1] = shp->inc[3];
     connect[2] = shp->inc[0];
     connect[3] = shp->inc[1];
     status = 1;
    }
    else if( (corners[1] == shp->inc[1]) && (corners[2] == shp->inc[6]) )
    {
     connect[1] = shp->inc[1];
     connect[2] = shp->inc[5];
     connect[3] = shp->inc[6];
     status = 1;
    }
    else if( (corners[1] == shp->inc[6]) && (corners[2] == shp->inc[3]) )
    {
     connect[1] = shp->inc[6];
     connect[2] = shp->inc[7];
     connect[3] = shp->inc[3];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[3] )
   {
    connect[0] = shp->inc[3];
    if( (corners[1] == shp->inc[0]) && (corners[2] == shp->inc[2]) )
    {
     connect[1] = shp->inc[0];
     connect[2] = shp->inc[1];
     connect[3] = shp->inc[2];
     status = 1;
    }
    else if( (corners[1] == shp->inc[2]) && (corners[2] == shp->inc[7]) )
    {
     connect[1] = shp->inc[2];
     connect[2] = shp->inc[6];
     connect[3] = shp->inc[7];
     status = 1;
    }
    else if( (corners[1] == shp->inc[7]) && (corners[2] == shp->inc[0]) )
    {
     connect[1] = shp->inc[7];
     connect[2] = shp->inc[4];
     connect[3] = shp->inc[0];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[4] )
   {
    connect[0] = shp->inc[4];
    if( (corners[1] == shp->inc[7]) && (corners[2] == shp->inc[5]) )
    {
     connect[1] = shp->inc[7];
     connect[2] = shp->inc[6];
     connect[3] = shp->inc[5];
     status = 1;
    }
    else if( (corners[1] == shp->inc[5]) && (corners[2] == shp->inc[0]) )
    {
     connect[1] = shp->inc[5];
     connect[2] = shp->inc[1];
     connect[3] = shp->inc[0];
     status = 1;
    }
    else if( (corners[1] == shp->inc[0]) && (corners[2] == shp->inc[7]) )
    {
     connect[1] = shp->inc[0];
     connect[2] = shp->inc[3];
     connect[3] = shp->inc[7];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[5] )
   {
    connect[0] = shp->inc[5];
    if( (corners[1] == shp->inc[4]) && (corners[2] == shp->inc[6]) )
    {
     connect[1] = shp->inc[4];
     connect[2] = shp->inc[7];
     connect[3] = shp->inc[6];
     status = 1;
    }
    else if( (corners[1] == shp->inc[6]) && (corners[2] == shp->inc[1]) )
    {
     connect[1] = shp->inc[6];
     connect[2] = shp->inc[2];
     connect[3] = shp->inc[1];
     status = 1;
    }
    else if( (corners[1] == shp->inc[1]) && (corners[2] == shp->inc[4]) )
    {
     connect[1] = shp->inc[1];
     connect[2] = shp->inc[0];
     connect[3] = shp->inc[4];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[6] )
   {
    connect[0] = shp->inc[6];
    if( (corners[1] == shp->inc[5]) && (corners[2] == shp->inc[7]) )
    {
     connect[1] = shp->inc[5];
     connect[2] = shp->inc[4];
     connect[3] = shp->inc[7];
     status = 1;
    }
    else if( (corners[1] == shp->inc[7]) && (corners[2] == shp->inc[2]) )
    {
     connect[1] = shp->inc[7];
     connect[2] = shp->inc[3];
     connect[3] = shp->inc[2];
     status = 1;
    }
    else if( (corners[1] == shp->inc[2]) && (corners[2] == shp->inc[5]) )
    {
     connect[1] = shp->inc[2];
     connect[2] = shp->inc[1];
     connect[3] = shp->inc[5];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[7] )
   {
    connect[0] = shp->inc[7];
    if( (corners[1] == shp->inc[6]) && (corners[2] == shp->inc[4]) )
    {
     connect[1] = shp->inc[6];
     connect[2] = shp->inc[5];
     connect[3] = shp->inc[4];
     status = 1;
    }
    else if( (corners[1] == shp->inc[4]) && (corners[2] == shp->inc[3]) )
    {
     connect[1] = shp->inc[4];
     connect[2] = shp->inc[0];
     connect[3] = shp->inc[3];
     status = 1;
    }
    else if( (corners[1] == shp->inc[3]) && (corners[2] == shp->inc[6]) )
    {
     connect[1] = shp->inc[3];
     connect[2] = shp->inc[2];
     connect[3] = shp->inc[6];
     status = 1;
    }
   }

   return( status );
}


/* ============================ GetShpDomainBRICK8 ========================= */

static void GetShpDomainBRICK8 ( Telement_3d    *shp,
                                 ShapeType *type,
                                 int       *num_nodes,
                                 int       connect[] )
{
   *type = NF_BRICK8;
   *num_nodes = 8;

   ConnectBRICK8( shp, connect );
}


/* ================================ MakeBRICK8 ============================= */

static void MakeBRICK8 ( Telement_3d *shp,
                         int    *connect )
{
   shp->inc[rs[0]] = connect[0];
   shp->inc[rs[1]] = connect[1];
   shp->inc[rs[2]] = connect[2];
   shp->inc[rs[3]] = connect[3];
   shp->inc[rs[4]] = connect[4];
   shp->inc[rs[5]] = connect[5];
   shp->inc[rs[6]] = connect[6];
   shp->inc[rs[7]] = connect[7];
}


/* ============================ MakeDefaultBRICK8 ========================== */

static void MakeDefaultBRICK8 ( Telement_3d *shp,
                                int    *connect )
{
   shp->inc[0] = connect[0];
   shp->inc[1] = connect[1];
   shp->inc[2] = connect[2];
   shp->inc[3] = connect[3];
   shp->inc[4] = connect[4];
   shp->inc[5] = connect[5];
   shp->inc[6] = connect[6];
   shp->inc[7] = connect[7];
}




/* =========================== NumNodesBRICK8 =============================== */

static int NumNodesBRICK8( Telement_3d *shp )
{
   ignore (shp);

   return ( 8 );
}


/* ============================= ReadBRICK8 ================================= */

static int ReadBRICK8( Telement_3d *shp, int *conn )
{
   int i;

   for (i=0;i<8;i++)
     shp->inc[rs[i]] = conn[i];

   return( TRUE );
}


/* =========================================================== End of File */
